﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using FunMazeEngine;
using System.Runtime.Remoting;
using System.Threading;

namespace GameServer
{
    [Serializable]
    internal class Mediator : MarshalByRefObject, IMediator
    {
        public Game game;
        bool gameStart = false;
        int totalcells = 0;
        int mapsize = 0;

        //private ArrayList playerList;
        
        //private string[] errorMessages = { "Player already exists" };

        //public Mediator()
        //{
        //    this.playerList = new ArrayList();           
        //}

        //#region IMediator Members

        //public bool JoinGame(IClientImplement ici)
        //{
        //    bool result = false;
        //    if (ici != null)
        //    {
        //        try
        //        {
        //            // First check with the unique user
        //            foreach (IClientImplement icc in this.playerList)
        //            {
        //                if (icc.PlayerName.CompareTo(ici.PlayerName) == 0)
        //                {
        //                    result = false;                           
        //                }
        //            }

        //            this.playerList.Add(ici);
        //            Console.WriteLine("--------------------Joining of new player----------------------");
        //            Console.WriteLine(ici.PlayerName + " joined game at: " + DateTime.Now.ToString());
        //            Console.WriteLine("----------------------------------------------------------");

        //            foreach (IClientImplement icimp in this.playerList)
        //            {
        //                ici.PlayerList = this.playerList;                        
        //            }

        //            result = true;
        //        }
        //        catch (RemotingException ex)
        //        {
        //            Console.WriteLine(ex.Message);
        //            Console.WriteLine(ex.StackTrace);
        //            result = false;                    
        //        }
        //    }

        //    return result;
        //}

        //public void SendMessageToPlayers(IClientImplement ici)
        //{
        //    try
        //    {
        //        foreach (IClientImplement icimp in this.playerList)
        //        {
        //            icimp.SendMessageToPlayers(ici);
        //        }
        //    }
        //    catch (RemotingException ex)
        //    {
        //        Console.WriteLine(ex.Message);
        //        Console.WriteLine(ex.StackTrace);
               
        //    }
        //}

        //public void RemovePlayer(IClientImplement ici)
        //{
        //    if (ici != null)
        //    {
        //        try
        //        {
        //            ArrayList temp = new ArrayList();

        //            Console.WriteLine("\n-------------Removal of player--------------------------\n");
        //            foreach (IClientImplement icm in this.playerList)
        //            {
        //                Console.WriteLine("User name: " + icm.PlayerName);
        //                if (icm.PlayerName.CompareTo(ici.PlayerName) != 0)
        //                {
        //                    Console.WriteLine("Added player name: " + icm.PlayerName);
        //                    temp.Add(icm);
        //                }
        //            }

        //            Console.WriteLine(ici.PlayerName + " left chat at: " + DateTime.Now.ToString());

        //            foreach (IClientImplement icimp in temp)
        //            {
        //                Console.WriteLine("Sending message to: " + icimp.PlayerName);
        //                ici.PlayerList = temp;
        //                icimp.PlayerLeft(ici);
        //            }

        //            this.playerList.Clear();
        //            foreach (IClientImplement icm in temp)
        //            {
        //                Console.WriteLine("Updating class array list. Adding: " + icm.PlayerName);
        //                this.playerList.Add(icm);
        //            }
        //            Console.WriteLine("\n--------------------------------------------\n");
        //        }
        //        catch (RemotingException ex)
        //        {
        //            Console.WriteLine("\n\nError occured. Message:" + ex.Message);
        //            Console.WriteLine("Stack trace: " + ex.StackTrace);                    
        //        }
        //    }
        //}       

        //#endregion

        //public override object InitializeLifetimeService()
        //{
        //    return null;
        //}

        public bool CreateGame(IGameClient clientObject, int mazePara, int treasureCount)
        {
            try
            {
                Random random = new Random();
                Map gameMap = new Map();
                gameMap.CreateMap(mazePara, treasureCount);
                mapsize = mazePara;

                game = new Game();
                game.GameMap = gameMap;         
                
                game.AddPlayer(clientObject);
                totalcells = gameMap.GetTotalCells();
                clientObject.Player.Location = random.Next(0, totalcells);
                int thisrow, thiscolumn = 0;
                game.GameMap.GetRowColumnLocation(clientObject.Player.Location, out thisrow, out thiscolumn);
                game.GameMap.PlayerGetTreasure(clientObject.Player, thisrow, thiscolumn);

                return true;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.StackTrace);
                return false;

            }
        }

        public bool GameExists()
        {
            if (mapsize == 0) return false;
            else return true;
        }

        public bool StartGame()
        {
            Thread.Sleep(20000);
            gameStart = true;
            return gameStart;
        }

        public bool JoinGame(IGameClient clientObject)
        {
            bool joinGameResult = false;

            try
            {
                {
                    if (!gameStart)
                    {
                        Random random = new Random();
                        game.AddPlayer(clientObject);
                        clientObject.Player.Location = -1;

                        while (clientObject.Player.Location == -1)
                        {
                            int spawnloc = random.Next(0, totalcells);
                            if (game.PlayerThere(spawnloc) == false)
                            {
                                clientObject.Player.Location = spawnloc;
                            }

                            /*
                             * if not occupied, add the player there(player.Location = spawnloc), else try again(do nothing).
                             */
                        }
                        int thisrow, thiscolumn = 0;
                        game.GameMap.GetRowColumnLocation(clientObject.Player.Location, out thisrow, out thiscolumn);
                        game.GameMap.PlayerGetTreasure(clientObject.Player, thisrow, thiscolumn);


                        joinGameResult = true;
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.StackTrace);
            }


            return joinGameResult;
        }

        public IGameClient GetGamePlayer(string name)
        {
            return game.RetrieveGamePlayer(name);
        }

        public void ExitGame(IGameClient clientObject)
        {
            game.RemovePlayer(clientObject); throw new NotImplementedException();
        }

        public bool PlayerMoveEast(IGameClient clientObject)
        {
            bool moveSuccess = false;
            if (gameStart)
            {
                int currentLocation = clientObject.Player.Location;
                int row = 0, column = 0;
                game.GameMap.GetRowColumnLocation(currentLocation, out row, out column);

                if (row == mapsize) { moveSuccess = false; }
                else
                {
                    row++;
                    int newlocation = game.GameMap.GetCellLocation(row, column);
                    if (game.PlayerThere(newlocation))
                    {
                        moveSuccess = false;
                    }
                    else
                    {
                        clientObject.Player.Location = game.GameMap.GetCellLocation(row, column);
                        moveSuccess = true;
                    }
                }

            }
            return moveSuccess;
        }

        public bool PlayerMoveWest(IGameClient clientObject)
        {
            bool moveSuccess = false;
            if (gameStart)
            {
                int currentLocation = clientObject.Player.Location;
                int row = 0, column = 0;
                game.GameMap.GetRowColumnLocation(currentLocation, out row, out column);

                if (row == 0) { moveSuccess = false; }
                else
                {
                    row--;
                    int newlocation = game.GameMap.GetCellLocation(row, column);
                    if (game.PlayerThere(newlocation))
                    {
                        moveSuccess = false;
                    }
                    else
                    {
                        clientObject.Player.Location = game.GameMap.GetCellLocation(row, column);
                        moveSuccess = true;
                    }
                }

            }
            return moveSuccess;
        }

        public bool PlayerMoveNorth(IGameClient clientObject)
        {
            bool moveSuccess = false;
            if (gameStart)
            {
                int currentLocation = clientObject.Player.Location;
                int row = 0, column = 0;
                game.GameMap.GetRowColumnLocation(currentLocation, out row, out column);

                if (column == 0) { moveSuccess = false; }
                else
                {
                    column--;
                    int newlocation = game.GameMap.GetCellLocation(row, column);
                    if (game.PlayerThere(newlocation))
                    {
                        moveSuccess = false;
                    }
                    else
                    {
                        clientObject.Player.Location = game.GameMap.GetCellLocation(row, column);
                        moveSuccess = true;
                    }
                }

            }
            return moveSuccess;

        }

        public bool PlayerMoveSouth(IGameClient clientObject)
        {
            bool moveSuccess = false;
            if (gameStart)
            {
                int currentLocation = clientObject.Player.Location;
                int row = 0, column = 0;
                game.GameMap.GetRowColumnLocation(currentLocation, out row, out column);

                if (column == mapsize) { moveSuccess = false; }
                else
                {
                    column++;
                    int newlocation = game.GameMap.GetCellLocation(row, column);
                    if (game.PlayerThere(newlocation))
                    {
                        moveSuccess = false;
                    }
                    else
                    {
                        clientObject.Player.Location = game.GameMap.GetCellLocation(row, column);
                        moveSuccess = true;
                    }
                }

            }
            return moveSuccess;

        }

        public void SendUpdateToPlayers(Game gameInfo)
        {            
            foreach (IGameClient player in game.gamePlayerList)
            {                
                player.SendUpdateToPlayer(gameInfo);                
            }

            
        }

        public void SendWelcomeMessageToPlayers(string message)
        {
            foreach (IGameClient player in game.gamePlayerList)
            {
                player.SendWelcomeMessageToPlayer(message);
            }
        }
    }
}
